<template>
    <div class="home">
        <div class="header"><span>chat ({{'在线:' + online + '人' }})</span>
            <User @click="showOnlineInfo" style="color:greenyellow;width: 0.4rem;position: relative;top: 0.1rem;left: 0.05rem;"></User>
        </div>
        <div class="main" id="main">
            <div class="list" v-for="(item,index) in messageList.list" :key="'messageList'+index">
                <!-- 时间 -->
                <span class="time" v-if="isShowTime(item,index)"> {{ timeFormat(item.time) }} </span>
                <!-- 对方的消息 -->
                <div class="user" v-if="item.userId != userId" :style="isShowTime(item,index)?'':'margin-top:0'">
                    <!-- 头像 -->
                    <div class="avator" @click="showInfo(item.userId)">
                        <img :src="BaseURL + item.avator" alt="">
                    </div>
                    <!-- 图文消息 -->
                    <img v-if="item.type=='img'" @click="previewImage(BaseURL+item.message)" :ref="setRefImg" class="message-img"
                        :src="BaseURL+item.message" alt="">
                    <!-- 文本消息 -->
                    <p v-if="item.type=='text'" class="message">
                        {{ item.message }}
                    </p>
                    <!-- 昵称 -->
                    <p class="username"> {{ item.name }} </p>
                </div>

                <!-- 本人的消息 -->
                <div class="user-own" v-else :style="isShowTime(item,index)?'':'margin-top:0'">
                    <!-- 图文消息 -->
                    <img v-if="item.type=='img'" @click="previewImage(BaseURL+item.message)" :ref="setRefImg" class="message-img"
                        :src="BaseURL+item.message" alt="">
                    <!-- 文本消息 -->
                    <p v-if="item.type=='text'" class="message"> {{ item.message }}</p>
                    <!-- 头像 -->
                    <div class="avator">
                        <img :src="BaseURL + item.avator" alt="" @click="showInfo(item.userId)">
                    </div>
                    <!-- 昵称 -->
                    <p class="username"> {{ item.name }} </p>
                </div>
            </div>

            <div class="new-message" v-if="isShowNewMsg" @click="toFooter(true)">
                <span>你有{{ showNewMsgNum }}新消息</span>
            </div>
        </div>
        <div class="footer">
            <Picture style="width: 0.7rem;margin-right: 0.1rem;" @click="sendPicture"></Picture>
            <VideoCamera style="width: 0.7rem;margin-right: 0.1rem;" @click="openVideoCall"></VideoCamera>
            <el-input v-model="messageVal" ref="input"></el-input>
            <el-button type="primary" @click="sendMessage">发送</el-button>
        </div>
    </div>
    <Drawer :visible="visible" type="right" show-close @close='onDrawerClose'>
        <div v-for="(item,index) in onlineUserList" :key="'onlineUserList'+index" class="userlist">
            <div class="avator" @click="showInfo(item.id)">
                <img :src="BaseURL + item.avator" alt="">
            </div>
            <div>{{ item.name }}</div>
        </div>
    </Drawer>
</template>

<script setup>
import { ref, reactive, onMounted, onBeforeUnmount, onBeforeMount, nextTick } from 'vue'
import $http, { IP, BaseURL } from '@/api'
import { showImagePreview } from 'vant';
import previewImage from '@/assets/js/previewImage.js'
import router from '@/router';
import { User, VideoCamera, Picture } from '@element-plus/icons-vue';
import { Upload } from 'qiaonan'
import { message, loading } from '@/public'
import Drawer from '@/components/drawer.vue'

/**
 * @Author dingxing [2023-02-28 15:20:47]
 * @Description 
 */
const messageVal = ref('');

const isShowNewMsg = ref(false);
const showNewMsgNum = ref(0);

const input = ref(null);
const refImgArr = ref([]);

const online = ref(0);
const onlineUserIds = ref([]);
const onlineUserList = ref([]);
const visible = ref(false);

let timeBarOnline = null;
const messageList = reactive({
    list: []
});
const userId = localStorage.getItem('id');
const name = localStorage.getItem('name');
const avator = localStorage.getItem('avator');
const token = localStorage.getItem('token');

let socket = '';
onBeforeMount(() => {
    getMessageList();
    initSocket(userId);
});

onMounted(() => {
    // const main = document.getElementById('main');
    nextTick(() => {
    });
});

onBeforeUnmount(() => {
    clearInterval(timeBarOnline);
})
// 发送图片
const sendPicture = () => {
    let ld = null;
    Upload({
        url: BaseURL + '/sendImg',
        headers: {
            'user-id': localStorage.getItem('id'),
            'token':localStorage.getItem('token')
        },
        data: {
            avator,
            name,
        },
        multiple: true,
        accept: "image/*",
        onConfirm(formdata) {
            // 确定键往表单添加 字段
            formdata.append('time', new Date().format('yyyy-MM-dd hh:mm'));
            ld = loading({ text: "发送中..." });
        },
        onSuccess(res) {
            // console.log(res) 
            ld.close();
            if (res.code == 1) {
                message({ type: 'success', text: res.message });
            } else {
                if (res.code == -1) {
                    message({ type: 'info', text: res.message });
                    setTimeout(() => {
                        router.replace('/')
                    }, 1000);
                    return
                }
                message({ type: 'info', text: res.message });
            }
        },
        onError() {
            ld.close();
            message({ type: 'error', text: '网络错误' });
        }
    })
};
// 打开视频通话
const openVideoCall = () => {
    window.open(`/video.html`);
};
// 设置refs 图片
const setRefImg = (el) => {
    if (el) {
        refImgArr.value.push(el);
    }
};
// 监听图片加载完毕
const onImageLoad = () => {
    refImgArr.value.forEach((item) => {
        if (item.complete) return
        item.onload = () => { toFooter() }
    })
}
// 是否显示time
const isShowTime = (item, index) => {
    return item.time !== messageList.list[index - 1]?.time
};

// 发送消息
const sendMessage = () => {
    if (!messageVal.value) return;
    socket.send(JSON.stringify({
        message: messageVal.value,
        avator: avator,
        name: name,
        time: new Date().format('yyyy-MM-dd hh:mm')
    }))
    messageVal.value = "";
    // 聚焦
    focus();
};
// 初始化
const initSocket = (userId) => {

    socket = new WebSocket(`ws://${IP}/connect?token=${token}`, userId);
    socket.onopen = onopen;
    socket.onmessage = socketOnMessage;
    socket.onclose = onclose;
};
// 监听消息
const socketOnMessage = ({ data }) => {
    let result = JSON.parse(data);
    console.log(result, '===')
    const { type, isExitsUser, message: msg, onlinePerson } = result;
    online.value = onlinePerson?.num;
    onlineUserIds.value = onlinePerson?.userIds;
    // 判断用户是否存在
    if (isExitsUser) {
        message({ type: 'error', text: msg });
        setTimeout(() => {
            router.replace('/');
        }, 2000);
        return
    }
    // 撤回消息
    if (type == "backMessage") {
        message({ text: result.result.name + "撤回了一条消息", type: "info" });
        messageList.list.some((item, index) => {
            if (item.id === result.result.id) {
                messageList.list.splice(index, 1);
                return true
            }
        })
        return
    }
    // 添加消息
    messageList.list.push(result);
    if (result.userId == userId) {
        toFooter();
    } else {
        // 判断滚动条是否在底部
        isFooter();
    }
};
// 获取消息列表
const getMessageList = () => {
    $http.get('/messageList').then((data) => {
        messageList.list = data; //通过这样更新页面
        toFooter();
    })
};
// 聚焦
const focus = () => {
    input.value.focus();
};

// 判断是否在底部
const isFooter = () => {
    let div = document.getElementById('main');
    let height = div.offsetHeight;
    let scrollTop = div.scrollTop;
    let scrollHeight = div.scrollHeight;
    if (scrollHeight > height + scrollTop) {
        isShowNewMsg.value = true;
        showNewMsgNum.value++;
    } else {
        isShowNewMsg.value = false;
        toFooter();
    }
};

// 到底部
const toFooter = (flag = false) => {
    nextTick(() => {
        // 监听图片加载完毕
        onImageLoad();
        let div = document.getElementById('main');
        if (flag) {
            div.scrollTo({
                top: div.scrollHeight,
                behavior: 'smooth'
            })
            isShowNewMsg.value = false;
            showNewMsgNum.value = 0;
            return
        }
        div.scrollTop = div.scrollHeight;
    })
};

// 查看用户信息
const showInfo = (userId) => {
    router.push({ path: '/showInfo', query: { userId } })
};
const timeFormat = (string) => {
    // console.log(string)
    let stringDate = string.slice(0, 10);
    let stringTime = string.slice(10);
    let currentDate = new Date().format('yyyy-MM-dd');
    if (stringDate == currentDate) {
        return stringTime
    } else {
        return string
    }
};
// 查看在线信息
const showOnlineInfo = async () => {
    let len = onlineUserIds.value.length;
    onlineUserList.value = [];
    visible.value = true;
    try {
        for (let i = 0; i < len; i++) {
            let result = await $http.get('/getUserInfo', { userId: onlineUserIds.value[i] }, {}, {});
            onlineUserList.value.push(result);
        }
    } catch (error) {

    }

};
const onDrawerClose = () => {
    visible.value = false;
};

const onopen = () => {
    cl('socket链接成功');
    getonline(false);
    timeBarOnline = setInterval(() => {
        getonline(true);
    }, 3000);
};
const getonline = (flag = false) => {
    // 第四个参数是禁止loading
    $http.get('/getOnlinePerson', {}, {}, flag).then((res) => {
        online.value = res.onlinePerson.num;
        onlineUserIds.value = res.onlinePerson.userIds;
    })
};
const onclose = () => {
    cl("断开socket连接")
};
</script>

<style lang="less" scoped>
@import url('./less/home.less');
</style>